# 作者：石吴震
# 2025年01月09日12时12分11秒
# 474160957@qq.com

import re

result=re.match("wangdao","wangdao.cn") #re.match()能够匹配出以xxx开头的字符串
print(result.group()) #匹配的结果放入group()中

def single():
    single1_1=re.match(".","wangdao.cn") #匹配任意1个字符（除了\n）
    single1_2 = re.match("w.", "wangdao.cn")
    single1_3= re.match("w.n", "wangdao.cn")
    print(single1_1.group())
    print(single1_2.group())
    print(single1_3.group())

    single2_0_0 = re.match("w", "wangdao.cn")  # 匹配单个小写字母
    single2_0_1 = re.match("W", "Wangdao.cn")  # 匹配单个大写字母
    single2_0_2 = re.match("[wW]", "wangdao.cn")  # 大小写都行

    single2_1=re.match("[0-9]wangdao.cn","7wangdao.cn") #匹配[]中列举的字符
    single2_2=re.match("[0-35-7]wangdao.cn","7wangdao.cn") #匹配0-3,5-7中的任意一个数字
    # single2_3 = re.match("[0-35-7]wangdao.cn", "awangdao.cn")
    single2_4 = re.match("\dwangdao.cn", "7wangdao.cn") #匹配数字，即0-9decimal
    single2_5 = re.match("\Dwangdao.cn", "awangdao.cn") #匹配非数字，即不是数字
    single2_6 = re.match("\swangdao.cn", " wangdao.cn") #匹配空格
    single2_7 = re.match("\Swangdao.cn", "7wangdao.cn ") #匹配非空格
    single2_8 = re.match("\wwangdao.cn", "_wangdao.cn") #匹配字母数字下划线还有汉字
    single2_9 = re.match("\Wwangdao.cn", " wangdao.cn!") #匹配非字母数字下划线还有汉字

    print(single2_0_0.group())
    print(single2_0_1.group())
    print(single2_0_2.group())
    print(single2_1.group())
    print(single2_2.group())
    # print(single2_3.group())
    print(single2_4.group())
    print(single2_5.group())
    print(single2_6.group())
    print(single2_7.group())
    print(single2_8.group())
    print(single2_9.group())

def multiple():
    ret=re.match("[A-Z][a-z]*", "M") #*表示匹配前一个字符出现0次或者无限次
    print(ret.group())
    ret=re.match("[A-Z][a-z]*", "MnnM")
    print(ret.group())
    ret=re.match("[A-Z][a-z]*", "Aabcdef")
    print(ret.group())

    names=["name1","_name","2_name","__name__"]
    for name in names:
        ret=re.match("[a-zA-Z_]+[\w]*", name) #+表示匹配前一个字符出现1次或者无限次
        if ret:
            print("变量名% s符合要求"%ret.group())
        else:
            print("变量名% s非法"%name)

    ret=re.match("[1-9]?[0-9]", "7") #?表示匹配前一个字符出现0次或者1次
    print(ret.group())
    ret=re.match("[1-9]?\d", "33") #匹配0-99
    print(ret.group())
    ret=re.match("[1-9]?\d", "09") #同上
    print(ret.group())

    ret=re.match("[a-zA-Z0-9_]{6}", "12a3g45678") #匹配前一个字符出现m次
    print(ret.group())
    ret=re.match("[a-zA-Z0-9_]{8,20}", "1ad12f23s34455ff66") #匹配前一个字符出现m至n次
    print(ret.group())

    email_list=["xiaoWang@163.com","xiaoWang@163.comheihei",".com.xiaowang @ qq.com"]
    for email in email_list:
        ret=re.match("[\w]{4,20}@163\.com$",email) #^：匹配字符串开头；$：匹配字符串结尾；字符串中有'.'，需要转义(在前面加上\)
        if ret:
            print("%s是符合规定的邮件地址,匹配后的结果是:%s"%(email,ret.group()))
        else:
            print("%s不符合要求"%email)

def  group():
    # 匹配1-99
    # ret=re.match("[1-9][0-9]|[1-9]", "0") #匹配左右任意一个表达式,先匹配|左边的表达式，再匹配|右边的表达式
    # print(ret.group())
    # 匹配0-100
    ret=re.match("[1-9]?[0-9]|100", "0")
    print(ret.group())

    ret=re.match("\w{4,20}@163\.com","test@163.com")
    print(ret.group())
    #test @ 163.com
    ret=re.match("\w{4,20}@(163|126|qq)\.com","test@126.com") #()表示分组,(163|126|qq)表示163或126或qq
    print(ret.group())
    #test @ 126.com
    ret=re.match("\w{4,20}@(163|126|qq)\.com","test@qq.com")
    print(ret.group())
    #test @ qq.com
    ret=re.match("\w{4,20}@(163|126|qq)\.com","test@gmail.com")
    if ret:
        print(ret.group())
    else:
        print("不是163、126、qq邮箱")#不是163、126、qq邮箱
    ret=re.match("([^-]+)-(\d+)", "010-12345678")
    print(ret.group()) #010-12345678
    print(ret.group(1)) #010
    print(ret.group(2)) #12345678

    #通过引用分组中匹配到的数据即可，但是要注意是元字符串，即类似r""这种格式
    ret=re.match(r"<([a-zA-Z]*)>\w*</\1>","<html>hh</html>") #<\num>表示引用分组num匹配到的字符串,引用的分组要加（）
    print(ret.group())
    #因为2对<>中的数据不一致,所以没有匹配出来
    test_label="<html>hh</htmlbalabala>"
    ret=re.match(r"<([a-zA-Z]*)>\w*</\1>",test_label)
    if ret:
        print(ret.group())
    else:
        print("%s这是一对不正确的标签"%test_label)
    labels=["<html><h1>www.cskaoyan.com</h1></html>","<html><h1>www.cskaoyan.com</h2></html>"]
    for label in labels:
        ret=re.match(r"<(\w*)><(\w*)>.*</\2></\1>",label)
        if ret:
            print(ret.group())
        else:
            print("%s这是一对不正确的标签"%label)

    # (?P<name>)表示给分组起一个名字，方便后面引用，与\num引用分组的区别在于(?P<name>)是用名字来引用分组，而\num是用数字来引用分组
    # 注意格式：(?P=name)表示引用名字为name的分组
    ret=re.match(r"<(?P<tab1>\w*)><(?P<tab2>\w*)>.*</(?P=tab2)></(?P=tab1)>","<html><h1>www.cskaoyan.com</h1></html>")
    print(ret.group())
    ret=re.match(r"<(?P<tab1>\w*)><(?P<tab2>\w*)>.*</(?P=tab2)></(?P=tab1)>","<html><h1>www.cskaoyan.com</h2></html>")
    if ret:
        print("%s是符合要求的标签"%ret.group())
    else:
        print("%s不符合要求"%label)

def use_search():
    # search()方法只匹配第一个匹配项，如果字符串中有多个匹配项，只返回第一个匹配项
    ret=re.search(r"\d+","阅读次数为9999，点赞数为10000")
    print(ret.group())

#改进，re.finditer()返回一个迭代器，可以用next()方法获取下一个匹配项，直到没有匹配项时抛出StopIteration异常
def find_second_match(pattern,text):
    matches=re.finditer(pattern,text)
    try: #异常，不加也行
        next(matches)#跳过第一个匹配项
        # next(matches)#想获取第三个就要next两次
        second_match=next(matches)#获取第二个匹配项
        return second_match.group()
    except StopIteration:
        return None

def use_findall():
    # findall()方法返回所有匹配项的列表
    ret=re.findall(r"\d+","python=9999,c=7890,c++=12345")
    print(ret)

def use_sub():
    # sub()方法用于替换字符串中的匹配项
    # 将匹配到的阅读次数加1
    ret=re.sub(r"\d+",'998',"python=997") #ret=re.sub(r"\d+",add,"python=997")也行
    print(ret)

    text="apple apple apple apple"
    pattern=r"apple"
    replacement="orange"
    new_text=re.sub(pattern,replacement,text, count=2) #只替换2个匹配项
    print(new_text)

def use_combination():
    # 组合使用
    s='hello world,now is 2020/7/20 18:48,现在是2020年7月20日18时48分。'
    ret_s=re.sub(r'年|月',r'/',s)
    ret_s=re.sub(r'日',r' ',ret_s)
    ret_s=re.sub(r'时|分',r':',ret_s)
    print(ret_s)
    #findall有问题
    pattern=re.compile(r'\d{4}/[01]?[0-9]/[1-3]?[0-9]\s(0[0-9]|1[0-9]|2[0-4])\:[0-5][0-9]') #compile()方法将正则表达式编译成一个正则表达式对象，可以重复使用
    ret=pattern.findall(ret_s)
    print(ret)
    #应改为
    com = re.compile(r'\d{4}/[01]?[0-9]/[1-3]?[0-9]\s(?:0[0-9]|1[0-9]|2[0-4])\:[0-5][0-9]') #使用findall()方法时，分组中加?:,就能匹配全部了
    ret = com.findall(ret_s)
    print(ret)


if __name__ == '__main__':
    # single()
    # multiple()
    # group()
    # use_search()
    # text="abc123def456ghi789"
    # pattern=r"\d+"
    # second_match=find_second_match(pattern,text)
    # print(second_match)
    # use_findall()
    # use_sub()
    # use_combination()
    test_str= """<div>
        <p>岗位职责：</p>
<p>完成推荐算法、数据统计、接口、后台等服务器端相关工作</p>
<p><br></p>
<p>必备要求：</p>
<p>良好的自我驱动力和职业素养，工作积极主动、结果导向</p>
<p>&nbsp;<br></p>
<p>技术要求：</p>
<p>1、一年以上 Python 开发经验，掌握面向对象分析和设计，了解设计模式</p>
<p>2、掌握HTTP协议，熟悉MVC、MVVM等概念以及相关WEB开发框架</p>
<p>3、掌握关系数据库开发设计，掌握 SQL，熟练使用 MySQL/PostgreSQL 中的一种<br></p>
<p>4、掌握NoSQL、MQ，熟练使用对应技术解决方案</p>
<p>5、熟悉 Javascript/CSS/HTML5，JQuery、React、Vue.js</p>
<p>&nbsp;<br></p>
<p>加分项：</p>
<p>大数据，数理统计，机器学习，sklearn，高性能，大并发。</p>

        </div>
    """ #用"""..."""表示多行字符串

    ret=re.sub(r'<[^>]*>|\n|&nbsp;| ','',test_str)
    print(ret)